#ifndef WORLD_H
#define WORLD_H

#include "Cell.h"
#include "MonteCarloIterator.h"

class SimpleGrid;

/* world */
class World {
public:
	/* ctor */
	World(int width, int height);

	/* dtor */
	~World();

	/* setup : add cell */
	void addCell(Cell* cell);

	/* width/height get */
	int getWidth() const;
	int getHeight() const;

	/* grid */
//	CellId& grid(int x, int y);
	void setTile(int x, int y, CellId value);

	/* grid const */
	CellId grid(int x, int y) const;

	/* get cell */
	Cell* getCell(CellId id);
	Cell const* getCell(CellId id) const;

	/* new cell id */
	CellId getNewCellId() const;

	/* highest cell id */
	CellId getMaxCellId() const;

	/* simple grid copy */
	SimpleGrid* getSimpleGridCopy() const;

private:
	friend class MonteCarloIterator;
	friend class Physics;

	int _width;  /* width  */
	int _height; /* height */

	int _boundingBoxWidth;  /* bounding box width  */
	int _boundingBoxHeight; /* bounding box height */

	int _x1;
	int _x2;
	int _y1;
	int _y2;

	CellId* _grid;     /* grid data */
	Cell**  _idToCell; /* id => cell */

	MonteCarloIterator* _iterator;

	CellId _cellIdGenerator; /* cell id generation */
};

/* inline stuff */

///* grid */
//inline 
//CellId& World::grid(int x, int y) {
//	return _grid[y * _width + x];
//}

/* set tile */
inline 
void World::setTile(int x, int y, CellId value) {
	_grid[y * _width + x] = value;

	if (value != 0) {
		/* x */
		if (x < _x1) {
			_x1 = x;
			_boundingBoxWidth = _x2 - _x1 + 1;
			_iterator->updateCount();
		}
		if (x > _x2) {
			_x2 = x;
			_boundingBoxWidth = _x2 - _x1 + 1;
			_iterator->updateCount();
		}
		/* y */
		if (y < _y1) {
			_y1 = y;
			_boundingBoxHeight = _y2 - _y1 + 1;
			_iterator->updateCount();
		}
		if (y > _y2) {
			_y2 = y;
			_boundingBoxHeight = _y2 - _y1 + 1;
			_iterator->updateCount();
		}
	}
}

/* grid const */
inline
CellId World::grid(int x, int y) const {
	return _grid[y * _width + x];
}

#endif // WORLD_H

